﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AlgoImpl
{
    public class StepAnalyzer : IComparable
    {
        private List<string> m_FullShifts;
        private List<string> m_NotFullShifts;
        private List<string> m_NotArrangedWorkers;
        private Dictionary<string, List<string>> m_WorkersInShift;
        private Dictionary<string, List<string>> m_ShiftsOfWorker;
        private Statictics m_Stat;

        public Dictionary<string, List<string>> WorkersInShift { get { return m_WorkersInShift; } }

        public Dictionary<string, List<string>> ShiftsOfWorker { get { return m_ShiftsOfWorker; } }

        public static StepAnalyzer Create()
        {
            return new StepAnalyzer();
        }

        private StepAnalyzer() { }

        public List<string> NotFullShifts { get { return m_NotFullShifts; } }

        public List<string> NotArrangedWorkers { get { return m_NotArrangedWorkers; } }

        public Statictics Stat { get { return m_Stat; } }

        public void CollectDataFromGraphAfterAlgoFinished(ShiftRequests sr)
        {
            createResultData();
            initializeShifts();
            setWorkersRegisterdToShift();
            setShiftsThatWorkerIsRegisterdTo();
            setNotArrangedWorkers();
            initializeStat(sr.GetWantedShifts());
        }

        public List<string> GetWorkersInShift(Shift shift)
        {
            if (m_WorkersInShift.ContainsKey(shift.Id))
            {
                return m_WorkersInShift[shift.Id];
            }
            // throw notfound exception
            return null;
        }

        public List<string> GetShifsOfWorker(Worker worker)
        {
            if (m_ShiftsOfWorker.ContainsKey(worker.Id))
            {
                return m_ShiftsOfWorker[worker.Id];
            }
            // throw notfound exception
            return null;
        }

        private void initializeStat(Dictionary<string, List<string>> request)
        {
            m_Stat = new Statictics(request, m_ShiftsOfWorker);
        }

        private void createResultData()
        {
            m_FullShifts = new List<string>();
            m_NotArrangedWorkers = new List<string>();
            m_NotFullShifts = new List<string>();
            m_ShiftsOfWorker = new Dictionary<string, List<string>>();
            m_WorkersInShift = new Dictionary<string, List<string>>();
        }

        private void setNotArrangedWorkers()
        {
            foreach (DataNode node in Graph.Instance.GetAllNodesWithNeighboursWeight(-1))
            {
                m_NotArrangedWorkers.Add((node.Data));
            }
        }

        private void initializeShifts()
        {
            foreach (DataNode node in Graph.Instance.GetAllNodesFromSide(eSideInGraph.RIGHT))
            {
                Shift shift = (SharedData.Instance.GetShiftById(node.Data));
                if (shift.IsFull())
                {
                    m_FullShifts.Add(shift.Id);
                }
                else
                {
                    m_NotFullShifts.Add(shift.Id);
                }
            }
        }

        private void setWorkersRegisterdToShift()
        {
            foreach (DataNode node in Graph.Instance.GetAllNodesFromSide(eSideInGraph.RIGHT))
            {
                m_WorkersInShift.Add(node.Data, SharedData.Instance.GetShiftById(node.Data).GetAllWorkersIds());
            }
        }

        private void setShiftsThatWorkerIsRegisterdTo()
        {
            foreach (DataNode node in Graph.Instance.GetAllNodesFromSide(eSideInGraph.LEFT))
            {
                m_ShiftsOfWorker.Add(node.Data, SharedData.Instance.GetWorkerById(node.Data).GetAllShiftsIds());
            }
        }

        public int CompareTo(object obj)
        {
            int result = 0;
            if(obj.GetType() == typeof(StepAnalyzer))
            {
                StepAnalyzer fs = obj as StepAnalyzer;
                result = m_Stat.CompareTo(fs.Stat);
            }
            return result;
        }
 
    }
}